package cn.angis.flow.controller;

import cn.angis.common.model.R;
import cn.angis.db.controller.FlowBaseController;
import cn.angis.db.model.PageModel;
import cn.angis.db.model.PageOfResult;
import org.dromara.warm.flow.core.chart.BetweenChart;
import org.dromara.warm.flow.core.chart.FlowChart;
import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.service.ChartService;
import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.core.utils.MapUtil;
import org.dromara.warm.flow.core.utils.page.Page;
import org.dromara.warm.flow.orm.entity.FlowDefinition;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.DownloadedFile;
import org.noear.solon.core.handle.UploadedFile;
import org.noear.solon.data.annotation.Tran;
import org.noear.solon.data.annotation.Transaction;

import java.awt.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

/**
 * 流程定义Controller
 *
 * @author hh
 * @date 2023-04-11
 */
@Mapping("/flow/definition")
@Controller
public class DefController extends FlowBaseController {
    @Inject
    private DefService defService;

    @Inject
    private ChartService chartService;

    /**
     * 分页查询流程定义列表
     */
    @Mapping("/list")
    @Get
    public R<PageOfResult<Definition>> list(FlowDefinition flowDefinition, PageModel pageModel) {
        // flow组件自带分页功能
        Page<Definition> page = Page.pageOf(pageModel.getCurrent(), pageModel.getSize());
        page = defService.orderByCreateTime().desc().page(flowDefinition, page);
        PageOfResult pageOfResult = new PageOfResult();
        pageOfResult.setCurrent(page.getPageNum());
        pageOfResult.setSize(page.getPageSize());
        pageOfResult.setTotal(page.getTotal());
        pageOfResult.setRecords(page.getList());
        return success(pageOfResult);
    }


    /**
     * 获取流程定义详细信息
     */
    @Mapping(value = "/{id}")
    @Get
    public R<Definition> get(Long id) {
        return success(defService.getById(id));
    }

    /**
     * 新增流程定义
     */
    @Mapping("/save")
    @Post
    @Transaction
    public R<Boolean> save(FlowDefinition flowDefinition) {
        return success(defService.saveAndInitNode(flowDefinition));
    }

    /**
     * 发布流程定义
     */
    @Mapping("/publish/{id}")
    @Get
    @Transaction
    public R<Boolean> publish(Long id) {
        return success(defService.publish(id));
    }

    /**
     * 取消发布流程定义
     */
    @Mapping("/unPublish/{id}")
    @Get
    @Transaction
    public R<Void> unPublish(Long id) {
        defService.unPublish(id);
        return success();
    }

    /**
     * 修改流程定义
     */
    @Mapping("/update")
    @Post
    @Transaction
    public R<Boolean> edit(FlowDefinition flowDefinition) {
        return success(defService.updateById(flowDefinition));
    }

    /**
     * 删除流程定义
     */
    @Mapping("/delete/{ids}")
    @Post
    @Transaction
    public R<Boolean> remove(List<Long> ids) {
        return success(defService.removeDef(ids));
    }

    /**
     * 复制流程定义
     */
    @Mapping("/copyDef/{id}")
    @Get
    @Transaction
    public R<Boolean> copyDef(Long id) {
        return success(defService.copyDef(id));
    }

    @Mapping("/importDefinition")
    @Transaction
    public R<Void> importDefinition(UploadedFile file) throws Exception {
        defService.importIs(file.getContent());
        return success();
    }

    @Mapping("/exportDefinition/{id}")
    @Post
    public DownloadedFile exportDefinition(Long id, Context ctx) {
        // 要导出的字符串
        String content = defService.exportJson(id);
        Definition definition = defService.getById(id);
        return new DownloadedFile("text/json", content.getBytes(StandardCharsets.UTF_8), definition.getFlowCode() + "_" + definition.getVersion() + ".json");
    }

//    /**
//     * 查询流程图
//     *
//     * @param definitionId
//     *
//     * @return
//     */
//    @Mapping("/chartDef/{definitionId}")
//    @Get
//    public R<String> chartDef(Long definitionId) {
//        return success(chartService.chartDef(definitionId));
//    }

//    /**
//     * 查询流程图
//     *
//     * @param instanceId
//     * @return
//     */
//    @Mapping("/flowChart/{instanceId}")
//    @Get
//    public R<String> flowChart(Long instanceId) {
//        return success(chartService.chartIns(instanceId, (flowChartChain) -> {
//            List<FlowChart> flowChartList = flowChartChain.getFlowChartList();
//            flowChartList.forEach(flowChart -> {
//                if (flowChart instanceof BetweenChart) {
//                    BetweenChart betweenChart = (BetweenChart) flowChart;
//                    Map<String, Object> extMap = betweenChart.getNodeJson().getExtMap();
//                    // 给节点顶部增加文字说明
////                    betweenChart.topText("办理时间: 2025-02-08 12:12:12", Color.red);
//                    if (MapUtil.isNotEmpty(extMap)) {
//                        for(Map.Entry<String, Object> entry : extMap.entrySet()){
//                            // 给节点中追加文字
//                            betweenChart.addText(entry.getKey() + ":", Color.red);
//                            betweenChart.addText((String) entry.getValue(), Color.red);
//                        }
//                    }
//                }
//            });
//        }));
//    }

    /**
     * 激活流程
     *
     * @param definitionId
     * @return
     */
    @Mapping("/active/{definitionId}")
    @Get
    public R<Boolean> active(Long definitionId) {
        return success(defService.active(definitionId));
    }

    /**
     * 挂起流程
     *
     * @param definitionId
     * @return
     */
    @Mapping("/unActive/{definitionId}")
    @Get
    public R<Boolean> unActive(Long definitionId) {
        return success(defService.unActive(definitionId));
    }
}
